package com.fcy.fcy.view_test

import android.animation.TypeEvaluator
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View
import android.view.animation.LinearInterpolator
import androidx.core.content.ContextCompat
import androidx.core.graphics.withTranslation
import com.fcy.fcy.R
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.sin

class Circle @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
    private var mWidth = 0F
    private var mHeight = 0F
    private var radius = 0F
    private var angle = 0F
    private val bezierPath = Path()
    private val solidWhitePaint: Paint = Paint().apply {
        style = Paint.Style.STROKE
        color = ContextCompat.getColor(context, R.color.white)
        strokeWidth = 3f
        isAntiAlias = true
    }
    private val dotPaint = Paint().apply {
        style = Paint.Style.FILL
        isAntiAlias = true
        strokeWidth = 5F
        color = ContextCompat.getColor(context, R.color.white)
    }
    private val strokeCirclePaint: Paint = Paint().apply {
        style = Paint.Style.STROKE
        pathEffect = DashPathEffect(floatArrayOf(20F, 20F), 0F)
        color = ContextCompat.getColor(context, R.color.purple_200)
        strokeWidth = 3f
    }
    private val textPaint = Paint().apply {
        textSize = 40F
        typeface = Typeface.SERIF
        color = ContextCompat.getColor(context, R.color.white)
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        mWidth = w.toFloat()
        mHeight = h.toFloat()
        radius = if (mWidth < mHeight / 2) mWidth / 2 - 30 else mHeight / 4 - 30
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        canvas?.apply {
            drawWhiteLine(this)
            drawStrokeCircle(this)
            drawMaker(this)
            drawRadius(this)
            drawBezierCurve(this)
        }
    }

    private fun drawMaker(canvas: Canvas) {
        canvas.drawRect(10F, 10F, 210F, 110F, solidWhitePaint)
        canvas.drawText("fcyy", 50F, 70F, textPaint)
    }

    private fun drawWhiteLine(canvas: Canvas) {
        canvas.drawLine(0F, mHeight / 2, mWidth, mHeight / 2, solidWhitePaint)
        canvas.drawLine(0F, mHeight / 4 * 3, mWidth, mHeight / 4 * 3, solidWhitePaint)
        canvas.drawLine(mWidth / 2, 0F, mWidth / 2, mHeight, solidWhitePaint)
    }

    private fun drawStrokeCircle(canvas: Canvas) {
        canvas.withTranslation(mWidth / 2, mHeight / 4 * 3) {
            drawCircle(0F, 0F, radius, strokeCirclePaint)
        }
    }

    private fun drawRadius(canvas: Canvas) {
        canvas.withTranslation(mWidth / 2, mHeight / 4 * 3) {
            // 从圆心到圆上一点
            drawCircle(radius * cos(angle), radius * sin(angle), 5f, dotPaint)
            drawCircle(radius * cos(angle), -1 * radius * sin(angle), 5f, dotPaint)
            drawCircle(radius * cos(angle), -mHeight / 4, 5f, dotPaint)
            drawLine((radius * cos(angle)), radius * sin(angle), radius * cos(angle), -mHeight / 4, strokeCirclePaint)
            drawLine(0F, 0F, (radius * cos(angle)), radius * sin(angle), solidWhitePaint)
            drawLine(radius * cos(angle), -radius * sin(angle), radius * cos(angle), (radius * sin(angle)), solidWhitePaint)
        }
    }

    private var animator: ValueAnimator? = null
    fun start() {
        if (animator == null)
            animator = ValueAnimator.ofFloat(0F, 2 * PI.toFloat()).apply {
                repeatCount = -1
                duration = 10 * 1000
                setEvaluator(Eval())
                interpolator = LinearInterpolator()
                start()
            }
        else animator!!.resume()
    }

    fun stop() {
        animator?.pause()
    }

    /**
     * 绘制贝塞尔曲线
     */
    private fun drawBezierCurve(canvas: Canvas) {
        canvas.withTranslation(mWidth / 2, mHeight / 2) {
            val sampleCount = 50
            val dy = mHeight / 2 / sampleCount
            bezierPath.reset()
            bezierPath.moveTo(radius * cos(-angle), 0F)
            repeat(50) {
                val x = radius * cos(it * 0.15 - angle)
                val y = -dy * it
                bezierPath.quadTo(x.toFloat(), y, x.toFloat(), y)
            }
            drawPath(bezierPath, strokeCirclePaint)
            drawTextOnPath("O(∩_∩)O", bezierPath, 1000F, 10F, textPaint)
        }
    }

    inner class Eval : TypeEvaluator<Float> {
        override fun evaluate(fraction: Float, startValue: Float, endValue: Float): Float {
            angle = -fraction * endValue
            invalidate()
            return angle
        }
    }
}


private const val TAG = "Circle"
